#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <csignal>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

#include "sis3100_vme_calls.h"
#include "IOError.h"
#include "DigitalIO_DL636F.h"

using namespace std;

//taken, from /etc/dackel.cfg, might have to be changed...
int io_addr              = 0x8800;
char *dev_fn             = (char *) "/dev/sis1100_00remote";
											 
int crate                = -1;
DigitalIO_DL636F    *io;

void signal_handler(int signal);
void init_hw();
void safe_exit(int r);


/*****************************************************************************/
int main(int argc, char *argv[])
/*****************************************************************************/
{
		cerr << "sendpulse, built " << __DATE__ << " " << __TIME__ << endl;

		signal(SIGINT,signal_handler); // install handler for CTRL-C

		init_hw();

		//THE FOLLOWIN IS COPIED FROM dackel:
		// inform NOMAD about ending dackel
 		// sending 10 ttl pulses (converted from nim)
		// changed on 2007/03/05 after communication with Paolo
		cerr << "inform NOMAD" << flush;
		for(int i=0; i<30; i++ ) {
				io->setO4(1);
				// usleep(1);
				io->setO4(0);
				// usleep(100);
				cerr << ".";
		}
		cerr << "finished" << endl;

		close(crate);

		return 0;
}
/*****************************************************************************/


/*---------------------------------------------------------------------------*/
void init_hw()
/*---------------------------------------------------------------------------*/
{
		// open sis1100/3100 pci-to-vme link
		if( !(crate=open(dev_fn, O_RDWR, 0)) )
		{
				cerr << "ERROR: could not open \"" << dev_fn << "\"" << endl;
				cerr.flush(); exit(1);
		}

		io     = new DigitalIO_DL636F(crate,io_addr);

		cerr << "initializing hardware:\n";

		cerr << "vmesysreset..." << flush;
		if(int r=vmesysreset(crate)) {
				cerr << "error: vmesysreset() returned " << r << endl << endl;
				cerr.flush();
				safe_exit(1);
		}
//		cerr << "ok, sleeping 1 sec..."; 
//		sleep(1);
		cerr << "ok, ";

		try {
				// init io
				cerr << "io..." << flush;
				io->setOutputs(0); //set all output to zero
				cerr << "ok, ";
		} catch(IOError ioe) {
				cerr << "catched IOError:\n" << ioe.getMsg() << endl
						 << "param: "
						 << ioe.getParam() << " (signed) = "
						 << (u_int32_t)ioe.getParam() << " (unsigned) = " << hex
						 << ioe.getParam() << " (hex)\n\n"
						 << "strerror() returns: " << strerror(errno)
						 << endl << endl;

				safe_exit(1);
		}
}
/*---------------------------------------------------------------------------*/



/*---------------------------------------------------------------------------*/
void signal_handler(int signal)
/*---------------------------------------------------------------------------*/
{
		if(signal == SIGINT) {
				cerr << "\n\nCTRL-C pressed\n";
				safe_exit(2);
		} else
				psignal(signal, "signal_handler(): unknown signal!");
}
/*---------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------*/
void safe_exit(int r)
/*---------------------------------------------------------------------------*/
{
		cerr << "\nsafe_exit()\n";

    if(crate > -1 ) {
				cerr << "vmesysreset...";
				if(int r=vmesysreset(crate)) {
						cerr << "error: vmesysreset() returned " << r << endl << endl;
						cerr.flush(); exit(1);
				}
				sleep(1);	cerr << "ok\n";

				cerr << "closing crate\n\n"; close(crate);
		}

		exit(r);
}
/*---------------------------------------------------------------------------*/
